<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="Content-Script-Type" content="text/javascript">
    <style type="text/css">
        body { font-family: sans-serif }
        #selectionForm { text-align: center }
        #visDiv { margin-top: 0.25in }
        .note { font-size: small }
    </style>
    <script type="text/javascript" src="../jslibs/protovis-d3.2.js"></script>
    <script type="text/javascript" src="Franklin district item data.js"></script>
    <script type="text/javascript">

var currentSubject;  // cache subject selection
var currentGrade;  // cache grade selection
var sense = 'color';  // sensory mode: 'color'; 'height'

function getSubject() {
    var nodes = document.getElementById('subjectSelect').childNodes;
    var i;  // index of option
    for (i = 0; nodes[i]; i++) {
        if (nodes[i].nodeName != 'OPTION')
            continue;
        if (nodes[i].selected)
            return nodes[i].value;
    }
}

function getGrade() {
    var nodes = document.getElementById('gradeSelect').childNodes;
    var i;  // index of option
    for (i = 0; nodes[i]; i++) {
        if (nodes[i].nodeName != 'OPTION')
            continue;
        if (nodes[i].selected)
            return Number(nodes[i].value);
    }
}

function getSense() {
    var senses = document.getElementsByName('senseSelect');
    var i;
    for (i = 0; i < senses.length; i++)
        if (senses[i].checked) {
            sense = senses[i].value;
            return;
        }
}

function itemOrder(itemNumA, itemNumB) {
    // Sort numbers first, then non-numeric labels like "WP1".
    var numA = Number(itemNumA),
        numB = Number(itemNumB);
    if (numA && numB)
        return numA - numB;
    if (numA)
        return -1;
    if (numB)
        return 1;
    return pv.naturalOrder(itemNumA, itemNumB);
}

function arrangeItems() {
    // Return a filtered, nested array of item records.
    currentSubject = getSubject();
    currentGrade = getGrade();
    return pv.nest(franklin.filter(function(row) {
                return row.subject == currentSubject && row.grade == currentGrade;
                }))
        .key(function(row) { return row.district } )
        .key(function(row) { return row.itemNum } )
        .sortKeys(itemOrder)
        .entries()
        //.rollup(function(rows) { return pv.mean(rows, function(row) { return row.fractionScored } ) })
        ;
}

function sizeVisDiv(w, h, leftMargin) {
    var div = document.getElementById('visDiv');
    div.style.width = w + 'px';
    div.style.height = h + 'px';
}

function selectNote() {
    return;
    var note = document.getElementById('footNote');
    switch (sense) {
        case 'color':
            note.innerHTML = "Brighter colors indicate higher scores, darker colors lower scores.";
            break;
        case 'height':
            note.innerHTML = "Filled column heights indicate the fraction of possible points scored, from 0 to 100%.";
            break;
    }
    note.innerHTML += " Point to a cell to see the district, item number, subtopic, and percentage of possible points scored.";
}

function drawGraph() {
    var districts = arrangeItems();
    var cellSide = 20;
    var graphWidth = 50 * cellSide;  // allow for 50 questions
    var graphHeight = districts.length * cellSide;
    var districtNameWidth = 300;  // space for district names
    var itemNumberHeight = 10;  // space for item numbers
    var w = graphWidth + districtNameWidth;
    var h = graphHeight + itemNumberHeight;
    sizeVisDiv(w, h, districtNameWidth);
    var maxDotSize = 100;
    getSense();
    var vis = new pv.Panel()  // root panel
        .canvas('visDiv')
        .width(w)
        .height(h)
        ;
    var row = vis.add(pv.Panel)  // district row
        .data(districts)
        .height(cellSide)
        .top(function() { return this.index * cellSide } )
        .left(districtNameWidth)
        ;
    var cell = row.add(pv.Bar)  // item cell
        .width(cellSide)
        .data(function(districtEntry) { return districtEntry.values } )
        .left(function(itemEntry) { return this.index * cellSide } )
        .fillStyle(
            function(itemEntry) { 
                switch (sense) {
                case 'color':
                    var green = Math.floor(itemEntry.values[0].fractionScored * 255); 
                    return pv.color('rgb(0,' + green + ',0)');
                case 'size':
                    return pv.color('lightgray');
                default:
                    return pv.color('white');
                } 
            })
        .title(function(itemEntry) { var row = itemEntry.values[0];
                return row.district + 
                    ' item ' + row.itemNum + ', ' + row.questionType + 
                    ' ' + row.strand + 
                    ': ' + (Number(row.fractionScored) * 100).toFixed() + '%' } )
        ;
    cell.add(pv.Bar)  // performance bar
        .visible(sense == 'height')
        .bottom(0)
        .height(function(itemEntry) { return Number(itemEntry.values[0].fractionScored) * cellSide } )
        .fillStyle('gray')
        .title(function(itemEntry) { var row = itemEntry.values[0];
                return row.district + 
                    ' item ' + row.itemNum + ', ' + row.questionType + 
                    ' ' + row.strand + 
                    ': ' + (Number(row.fractionScored) * 100).toFixed() + '%' } )
        ;
    cell.anchor('top')
        .add(pv.Label)  // item numbers
        .visible(function() { this.parent.parent.index == 0 } )
        .textBaseline('bottom')
        .textAlign('center')
        .text(function(itemEntry) { return itemEntry.key } )
        .parent
        .anchor('left')
        .add(pv.Label)  // district name
        .textAlign('right')
        .text(function(districtEntry) { return districtEntry.key } )
        ;
    cell.add(pv.Dot)  // performance dot
        .visible(sense == 'size')
        .top(cellSide / 2)
        .left(function() { return this.index * cellSide + cellSide / 2 } )
        .size(function(itemEntry) { return Number(itemEntry.values[0].fractionScored) * maxDotSize } )
        .fillStyle('gray')
        .strokeStyle('none')
        .title(function(itemEntry) { var row = itemEntry.values[0];
                return row.district + 
                    ' item ' + row.itemNum + ', ' + row.questionType + 
                    ' ' + row.strand + 
                    ': ' + (Number(row.fractionScored) * 100).toFixed() + '%' } )
        ;

    vis.render();
}

    </script>
</head>
<body>
    <form id="selectionForm">
        <p>Franklin Country school districts, MCAS 2010 
        <select id="subjectSelect" onchange="drawGraph()">
            <option selected>English
            <option>Math
            <option>Science
        </select>
        <label>grade 
            <select id="gradeSelect" onchange="drawGraph()">
                <option>3
                <option>4
                <option>5
                <option>6
                <option>7
                <option>8
                <option selected>10
            </select>
        </label>
        item performance as
        <label>
            <input type="radio" name="senseSelect" value="color" checked onchange="drawGraph()">
            color
        </label>
        <label>
            <input type="radio" name="senseSelect" value="height" onchange="drawGraph()">
            height
        </label>
        <label>
            <input type="radio" name="senseSelect" value="size" onchange="drawGraph()">
            size
        </label>
        </p>
    </form>
    <div id="visDiv">
        <script type="text/javascript">
            drawGraph();
        </script>
    </div>
    <p class="note" id="footNote">
</body>
</html>
